package com.figure.common.utils;

import org.apache.log4j.Logger;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * 文件操作工具类
 */
public class FileUtil {
    protected static final Logger log = Logger.getLogger(FileUtil.class);
    private static SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");


    public static void copyDirectory(File dir, String targetDir) {
        File newDir = new File(targetDir + "/" + dir.getName());

        if (newDir.exists()) {
            log.warn("The dir already exist:" + newDir);
            newDir.renameTo(new File(newDir.getAbsolutePath() + "/"
                    + dir.getName() + "_"
                    + ft.format(new Date())));
            newDir.delete();
        }
        if (log.isDebugEnabled()) {
            log.debug("Copy Dir :" + dir.getAbsolutePath() + " to "
                    + newDir.getAbsolutePath());
        }

        try {
            newDir.mkdirs();
            for (File file : dir.listFiles()) {
                moveFile(file, newDir.getAbsolutePath());
            }
            dir.delete();
        } catch (Exception e) {
            log.warn("Error:" + e, e);
        }
    }

    /**
     * 将源文件移至目标目录下
     *
     * @param srcFile
     * @param targetDir
     */
    public static void moveFile(File srcFile, String targetDir) {
        log.info("move file:"+srcFile.getName()+" TO " + targetDir);
        try {
            byte[] buffer = new byte[1024];
            int length = 0;
            DataInputStream dis = null;
            DataOutputStream dao = null;
            String destFilePath = targetDir + "/" + srcFile.getName();
            File targetFile = new File(destFilePath);
            if (targetFile.exists()) {
                log.warn("File already exist:" + targetFile.getAbsolutePath());
                //renameFileInSameDir(targetFile, ".old");
                targetFile.delete();
            }

            dao = new DataOutputStream(new BufferedOutputStream(
                    new FileOutputStream(destFilePath)));
            dis = new DataInputStream(new BufferedInputStream(
                    new FileInputStream(srcFile)));
            while (dis.available() > 0) {
                length = dis.read(buffer);
                dao.write(buffer, 0, length);
            }
            dao.close();
            dis.close();
            srcFile.delete();
        } catch (Exception e) {
            log.warn("移动文件[" + srcFile.getName() + "]异常", e);
        }
    }

    public static File renameFileInSameDir(File file, String subFix) {
        File targetFile = null;
        byte[] buffer = new byte[1024];
        int length = 0;
        DataInputStream dis = null;
        DataOutputStream dao = null;
        try {
            if (file.getName().indexOf(".") <= 0) {
                log.warn("File name error:" + file.getName());
                return null;
            }
            String targetFileName = file.getAbsolutePath().substring(0,
                    file.getAbsolutePath().lastIndexOf("."))
                    + subFix;

            log.info("Rename:" + file.getName() + " to:" + targetFileName);

            targetFile = new File(targetFileName);
            if (targetFile.exists()) {
                log.warn("File already exist:" + targetFile.getAbsolutePath());
            }

            dao = new DataOutputStream(new BufferedOutputStream(
                    new FileOutputStream(targetFileName)));
            dis = new DataInputStream(new BufferedInputStream(
                    new FileInputStream(file)));
            while (dis.available() > 0) {
                length = dis.read(buffer);
                dao.write(buffer, 0, length);
            }
            dao.close();
            dis.close();
            file.delete();
        } catch (Exception e) {
            log.warn("Error:" + e, e);
        }

        return targetFile;
    }

    public static String storeFile(String path, String content, String name) {
        return storeFile(path, content.getBytes(), name);
    }

    public static String storeFile(String path, byte[] content, String name) {
        return storeFile(path, content, name, false);
    }

    public static String storeFile(String path, byte[] content, String name,
                                   boolean overwrite) {
        if (path == null || content == null) {
            return null;
        }
        File targetFile = null;
        FileOutputStream dao = null;
        File dir;
        try {
            dir = new File(path);
            dir.mkdirs();
            targetFile = new File(dir.getAbsolutePath() + "/" + name);
            if (targetFile.exists()) {
                log.warn("File already exist:" + targetFile.getAbsolutePath());
                if (overwrite) {
                    targetFile.delete();
                } else {
                    return null;
                }
            }
            dao = new FileOutputStream(targetFile);
            dao.write(content);
            dao.flush();
            dao.close();
            log.info("Create file:" + targetFile.getAbsolutePath());
            return targetFile.getName();
        } catch (Exception e) {
            log.warn("Error:" + e, e);
        }

        return null;
    }

    public static byte[] getFileBytes(String filename) {
        BufferedInputStream reader = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            reader = new BufferedInputStream(new FileInputStream(filename));

            StringBuilder cb = new StringBuilder();

            byte[] array = new byte[1024];
            int count = 0;
            while (reader.available() > -1) {
                count = reader.read(array);
                if (count > 0) {
                    baos.write(array, 0, count);
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return baos.toByteArray();
    }

    public static byte[] getFileBytes(String filename, String encoding) {
        Reader reader = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            reader = new InputStreamReader(new FileInputStream(
                    filename), encoding);
            StringBuilder cb = new StringBuilder();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return baos.toByteArray();
    }


    /**
     * 递归查找文件
     *
     * @param baseDirName    查找的文件夹路径
     * @param targetFileName 需要查找的文件名
     * @param suffix         文件名后缀(xml)
     * @param fileList       返回带有文件全路径的列表
     */
    public static void findFiles(String baseDirName, String targetFileName, String suffix, List<String> fileList) {
        String tempName = null;
        //判断目录是否存在
        File baseDir = new File(baseDirName);
        if (!baseDir.exists() || !baseDir.isDirectory()) {
            log.debug("文件查找失败：" + baseDirName + "不是一个目录！");
            return;
        }
        String[] filelist = baseDir.list();
        for (int i = 0; i < filelist.length; i++) {
            File readfile = new File(baseDirName + File.separator + filelist[i]);
            if (readfile.isDirectory()) {
                findFiles(baseDirName + File.separator + filelist[i], targetFileName, suffix, fileList);
                continue;
            }
            tempName = readfile.getName();
            if (!tempName.endsWith(suffix)) {
                continue;
            }
            tempName = tempName.substring(0, tempName.lastIndexOf("."));
            if (tempName.equalsIgnoreCase(targetFileName)) {
                fileList.add(readfile.getAbsolutePath());
            }
        }
    }
}
